using AutoMapper;
using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.MaterialManage;
using RBAC.Domain.SalesManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.SalesManagement;
using System.Transactions;

namespace RBAC.Write.Api.Application.Handler.ERP.SalesManagement
{
    /// <summary>
    /// 新增销售订单处理器
    /// </summary>
    public class AddSalesOrderHandler : IRequestHandler<AddSalesOrderCommand, APIResult<long>>
    {
        private readonly IBaseRepository<SalesOrder> salesOrderRepository;
        private readonly IBaseRepository<SalesOrderDetail> salesOrderDetailRepository;
        private readonly IBaseRepository<Mater> materRepository;
        private readonly ILogger<AddSalesOrderHandler> logger;
        private readonly IMapper mapper;

        public AddSalesOrderHandler(
            IBaseRepository<SalesOrder> salesOrderRepository,
            IBaseRepository<SalesOrderDetail> salesOrderDetailRepository,
            IBaseRepository<Mater> materRepository,
            ILogger<AddSalesOrderHandler> logger,
            IMapper mapper)
        {
            this.salesOrderRepository = salesOrderRepository;
            this.salesOrderDetailRepository = salesOrderDetailRepository;
            this.materRepository = materRepository;
            this.logger = logger;
            this.mapper = mapper;
        }

        /// <summary>
        /// 处理新增销售订单请求
        /// </summary>
        /// <param name="request">新增请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>新增结果</returns>
        public Task<APIResult<long>> Handle(AddSalesOrderCommand request, CancellationToken cancellationToken)
        {
            APIResult<long> result = new APIResult<long>();

            try
            {
                logger.LogInformation("开始新增销售订单，客户名称：{CustomerName}，明细数量：{DetailCount}",
                    request.CustomerName, request.Details.Count);

                // 1. 数据验证
                if (!ValidateRequest(request, out string validationMessage))
                {
                    result.Code = APIEnums.Error;
                    result.Msg = validationMessage;
                    logger.LogWarning("销售订单数据验证失败：{Message}", validationMessage);
                    return Task.FromResult(result);
                }

                // 2. 验证物料是否存在
                var materIds = request.Details.Select(d => d.MaterId).Distinct().ToList();
                var existingMaters = materRepository.GetAll($"Id IN ({string.Join(",", materIds.Select((_, i) => $"@Id{i}"))})",
                    materIds.Select((id, i) => new { Key = $"@Id{i}", Value = (object)id }).ToDictionary(x => x.Key, x => x.Value));

                if (existingMaters.Count != materIds.Count)
                {
                    var existingMaterIds = existingMaters.Select(m => m.Id).ToList();
                    var missingMaterIds = materIds.Except(existingMaterIds).ToList();
                    result.Code = APIEnums.Error;
                    result.Msg = $"物料不存在：{string.Join(",", missingMaterIds)}";
                    logger.LogWarning("物料不存在：{MissingMaterIds}", string.Join(",", missingMaterIds));
                    return Task.FromResult(result);
                }

                using (TransactionScope transaction = new TransactionScope())
                {
                    try
                    {
                        // 3. 生成单据编码：SO + 年月日时分秒
                        string orderCode = GenerateOrderCode();
                        logger.LogInformation("生成销售订单编码：{OrderCode}", orderCode);

                        // 4. 创建销售订单主信息
                        var salesOrder = new SalesOrder
                        {
                            OrderCode = orderCode,
                            OrderType = request.OrderType,
                            OrderDate = request.OrderDate,
                            OrderStatus = "开立", // 新订单状态为"开立"
                            BusinessType = request.BusinessType,
                            BusinessStatus = request.BusinessStatus,
                            SalesDepartment = request.SalesDepartment,
                            SalesPersonId = request.SalesPersonId,
                            SalesPerson = request.SalesPerson,
                            SalesChannel = request.SalesChannel,
                            SupplyMode = request.SupplyMode,
                            CustomerName = request.CustomerName,
                            Receiver = request.Receiver,
                            Phone = request.Phone,
                            Address = request.Address,
                            DestinationCountry = request.DestinationCountry,
                            ContractNo = request.ContractNo,
                            PaymentTerms = request.PaymentTerms,
                            DeliveryDate = request.DeliveryDate,
                            DeliveryStatus = request.DeliveryStatus,
                            Remark = request.Remark,
                            CreateTime = DateTime.Now,
                            CreateUser = "system", // 这里应该从当前用户上下文获取
                            IsDeleted = false
                        };

                        // 5. 保存销售订单主信息
                        var salesOrderId = salesOrderRepository.Create(salesOrder);
                        if (salesOrderId <= 0)
                        {
                            throw new InvalidOperationException("销售订单创建失败");
                        }
                        logger.LogInformation("销售订单主信息创建成功，ID：{SalesOrderId}", salesOrderId);

                        // 6. 创建销售订单明细
                        var salesOrderDetails = new List<SalesOrderDetail>();
                        foreach (var detailCommand in request.Details)
                        {
                            var salesOrderDetail = new SalesOrderDetail
                            {
                                SalesOrderId = salesOrderId,
                                MaterId = detailCommand.MaterId,
                                Num = detailCommand.Num,
                                Price = detailCommand.Price,
                                Remark = detailCommand.Remark,
                                CreateTime = DateTime.Now,
                                CreateUser = "system", // 这里应该从当前用户上下文获取
                                IsDeleted = false
                            };
                            salesOrderDetails.Add(salesOrderDetail);
                        }

                        // 7. 批量保存销售订单明细
                        if (salesOrderDetails.Any())
                        {
                            var detailResult = salesOrderDetailRepository.CreateBatch(salesOrderDetails);
                            if (detailResult != salesOrderDetails.Count)
                            {
                                throw new InvalidOperationException($"销售订单明细创建失败：预期 {salesOrderDetails.Count} 条，实际创建 {detailResult} 条");
                            }
                            logger.LogInformation("销售订单明细创建成功，数量：{DetailCount}", detailResult);
                        }

                        // 8. 提交事务
                        transaction.Complete();

                        result.Code = APIEnums.Success;
                        result.Data = salesOrderId;
                        result.Msg = "销售订单创建成功";

                        logger.LogInformation("销售订单创建完成，订单ID：{SalesOrderId}，订单编码：{OrderCode}",
                            salesOrderId, orderCode);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "创建销售订单过程中发生错误：{Message}", ex.Message);
                        result.Code = APIEnums.Error;
                        result.Msg = "创建销售订单失败";
                        result.Data = 0;
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "新增销售订单失败：{Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "新增销售订单失败";
                result.Data = 0;
            }

            return Task.FromResult(result);
        }

        /// <summary>
        /// 验证请求数据
        /// </summary>
        /// <param name="request">请求数据</param>
        /// <param name="message">验证消息</param>
        /// <returns>验证结果</returns>
        private bool ValidateRequest(AddSalesOrderCommand request, out string message)
        {
            message = string.Empty;

            if (string.IsNullOrWhiteSpace(request.CustomerName))
            {
                message = "客户名称不能为空";
                return false;
            }

            if (request.Details == null || !request.Details.Any())
            {
                message = "销售订单明细不能为空";
                return false;
            }

            foreach (var detail in request.Details)
            {
                if (detail.MaterId <= 0)
                {
                    message = "物料ID无效";
                    return false;
                }

                if (detail.Num <= 0)
                {
                    message = "数量必须大于0";
                    return false;
                }

                if (detail.Price < 0)
                {
                    message = "单价不能为负数";
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// 生成销售订单编码：SO + 年月日时分秒
        /// </summary>
        /// <returns>订单编码</returns>
        private string GenerateOrderCode()
        {
            var now = DateTime.Now;
            return $"SO{now:yyyyMMddHHmmss}";
        }
    }
}
